BZOJ 3931: [CQOI2015]网络吞吐量 最大流
3931: [CQOI2015]网络吞吐量
Time Limit: 1 Sec
Memory Limit: 256 MB
题目连接
http://www.lydsy.com/JudgeOnline/problem.php?id=3931Description
路由是指通过计算机网络把信息从源地址传输到目的地址的活动,也是计算机网络设计中的重点和难点。网络中实现路由转发的硬件设备称为路由器。为了使数据包最快的到达目的地,路由器需要选择最优的路径转发数据包。例如在常用的路由算法OSPF(开放式最短路径优先)中,路由器会使用经典的Dijkstra算法计算最短路径,然后尽量沿最短路径转发数据包。现在,若已知一个计算机网络中各路由器间的连接情况,以及各个路由器的最大吞吐量(即每秒能转发的数据包数量),假设所有数据包一定沿最短路径转发,试计算从路由器1到路由器n的网络的最大吞吐量。计算中忽略转发及传输的时间开销,不考虑链路的带宽限制,即认为数据包可以瞬间通过网络。路由器1到路由器n作为起点和终点,自身的吞吐量不用考虑,网络上也不存在将1和n直接相连的链路。
Input
输入文件第一行包含两个空格分开的正整数n和m,分别表示路由器数量和链路的数量。网络中的路由器使用1到n编号。接下来m行,每行包含三个空格分开的正整数a、b和d,表示从路由器a到路由器b存在一条距离为d的双向链路。 接下来n行,每行包含一个正整数c,分别给出每一个路由器的吞吐量。
Output
输出一个整数,为题目所求吞吐量。
Sample Input
7 10
1 2 2
1 5 2
2 4 1
2 3 3
3 7 1
4 5 4
4 3 1
4 6 1
5 6 2
6 7 1
1
100
20
50
20
60
1
Sample Output
70
HINT
对于100%的数据,n≤500,m≤100000,d,c≤10^9
题意
题解:
跑最短路之后拆点,拆点来维护每个点最大扔出去的网络吞吐量
然后直接搞就好了……
这道题要爆int = =!
怒wa一发
代码:
//qscqesze #include <cstdio> #include <cmath> #include <cstring> #include <ctime> #include <iostream> #include <algorithm> #include <set> #include <bitset> #include <vector> #include <sstream> #include <queue> #include <typeinfo> #include <fstream> #include <map> #include <stack> typedef long long ll; using namespace std; //freopen("D.in","r",stdin); //freopen("D.out","w",stdout); #define sspeed ios_base::sync_with_stdio(0);cin.tie(0) #define maxn 110000 #define mod 10007 #define eps 1e-9 int Num; //const int inf=0x7fffffff; //§ß§é§à§é¨f§³ const ll Inf=0x3f3f3f3f3f3f3f3fll; inline ll read() { ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } //************************************************************************************** namespace NetFlow { const ll MAXN=100000,MAXM=1000000,inf=0x3f3f3f3f3f3f3f3fll; struct Edge { ll v,c,f,nx; Edge() {} Edge(ll v,ll c,ll f,ll nx):v(v),c(c),f(f),nx(nx) {} } E[MAXM]; ll G[MAXN],cur[MAXN],pre[MAXN],dis[MAXN],gap[MAXN],N,sz; void init(ll _n) { N=_n,sz=0; memset(G,-1,sizeof(G[0])*N); } void link(ll u,ll v,ll c) { E[sz]=Edge(v,c,0,G[u]); G[u]=sz++; E[sz]=Edge(u,0,0,G[v]); G[v]=sz++; } bool bfs(int S,int T) { static int Q[MAXN]; memset(dis,-1,sizeof(dis[0])*N); dis[S]=0; Q[0]=S; for (int h=0,t=1,u,v,it;h<t;++h) { for (u=Q[h],it=G[u];~it;it=E[it].nx) { if (dis[v=E[it].v]==-1&&E[it].c>E[it].f) { dis[v]=dis[u]+1; Q[t++]=v; } } } return dis[T]!=-1; } ll dfs(ll u,ll T,ll low) { if (u==T) return low; ll ret=0,tmp,v; for (ll &it=cur[u];~it&&ret<low;it=E[it].nx) { if (dis[v=E[it].v]==dis[u]+1&&E[it].c>E[it].f) { if (tmp=dfs(v,T,min(low-ret,E[it].c-E[it].f))) { ret+=tmp; E[it].f+=tmp; E[it^1].f-=tmp; } } } if (!ret) dis[u]=-1; return ret; } ll dinic(int S,int T) { ll maxflow=0,tmp; while (bfs(S,T)) { memcpy(cur,G,sizeof(G[0])*N); while (tmp=dfs(S,T,inf)) maxflow+=tmp; } return maxflow; } } using namespace NetFlow; int n,m; struct node { ll x,y; }; vector<node> EE[maxn]; ll d[maxn]; ll inq[maxn]; ll cost[maxn]; struct EEdge { ll x,y,z; }; EEdge edge[maxn]; vector<ll> U,V; int main() { n=read(),m=read(); for(int i=1;i<=m;i++) { edge[i].x=read(),edge[i].y=read(),edge[i].z=read(); EE[edge[i].x].push_back((node){edge[i].y,edge[i].z}); EE[edge[i].y].push_back((node){edge[i].x,edge[i].z}); } for(int i=0;i<=n;i++) d[i]=Inf; queue<int> Q; Q.push(1); d[1]=0; inq[1]=1; while(!Q.empty()) { int u = Q.front(); Q.pop(); inq[u]=0; for(int i=0;i<EE[u].size();i++) { node v = EE[u][i]; if(v.y+d[u]<d[v.x]) { d[v.x]=v.y+d[u]; if(!inq[v.x]) { Q.push(v.x); inq[v.x]=1; } } } } for(int i=1;i<=n;i++) { for(int j=0;j<EE[i].size();j++) { node v = EE[i][j]; if(d[i]+v.y==d[v.x]) U.push_back(i+n),V.push_back(v.x); } } init(100000); for(int i=1;i<=n;i++) { cost[i]=read(); if(i!=1&&i!=n) link(i,i+n,cost[i]); else link(i,i+n,inf); } for(int i=0;i<V.size();i++) link(U[i],V[i],inf); printf("%lld\n",dinic(1,2*n)); }